{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-09-14T07:48:47.731352Z",
     "start_time": "2025-09-14T07:48:39.779672Z"
    }
   },
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "img = cv2.imread(r'../data/cat.png')\n",
    "# 1. 高斯噪声\n",
    "def add_gaussian_noise(img, mean=0, sigma=25):\n",
    "    row, col, ch = img.shape\n",
    "    gauss = np.random.normal(mean, sigma, (row, col, ch))\n",
    "    noisy = img + gauss\n",
    "    return np.clip(noisy, 0, 255).astype(np.uint8)\n",
    "gauss_noisy_img = add_gaussian_noise(img)\n",
    "cv2.imshow('noisy_img', gauss_noisy_img)\n",
    "cv2.waitKey(0)\n",
    "\n",
    "# 2. 椒盐噪声\n",
    "def add_salt_pepper_noisy(img, salt_prob=0.01, pepper_prob=0.01):\n",
    "    noisy = np.copy(img)\n",
    "    # 盐噪声\n",
    "    salt_mask = np.random.random(img.shape[:2]) < salt_prob\n",
    "    noisy[salt_mask] = 255\n",
    "    # 椒噪声\n",
    "    pepper_mask = np.random.random(img.shape[:2]) < pepper_prob\n",
    "    noisy[pepper_mask] = 0\n",
    "    return noisy\n",
    "salt_peooer_noisy_img = add_salt_pepper_noisy(img)\n",
    "cv2.imshow('noisy_img', salt_peooer_noisy_img)\n",
    "cv2.waitKey(0)\n"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T07:56:38.298892Z",
     "start_time": "2025-09-14T07:56:38.275821Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 椒盐噪声原理\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "salt_prob = 0.01  # 1%的概率\n",
    "\n",
    "# 生成随机数矩阵\n",
    "random_matrix = np.random.random((5, 5))\n",
    "print(\"随机数矩阵 (0-1之间):\")\n",
    "print(random_matrix)\n",
    "print()\n",
    "\n",
    "# 创建盐噪声掩码\n",
    "salt_mask = random_matrix < salt_prob\n",
    "print(\"盐噪声掩码 (random_matrix < 0.01):\")\n",
    "print(salt_mask)\n",
    "print()\n",
    "\n",
    "# 统计结果\n",
    "total_pixels = 5 * 5\n",
    "true_count = np.sum(salt_mask)\n",
    "actual_prob = true_count / total_pixels\n",
    "\n",
    "print(f\"统计结果:\")\n",
    "print(f\"总像素数: {total_pixels}\")\n",
    "print(f\"True的数量: {true_count}\")\n",
    "print(f\"实际概率: {actual_prob:.3f} (理论概率: {salt_prob})\")"
   ],
   "id": "c15ba596c8f9e511",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "随机数矩阵 (0-1之间):\n",
      "[[0.75198943 0.60173189 0.97665489 0.03913062 0.6480549 ]\n",
      " [0.4964062  0.39268614 0.62380011 0.59807175 0.01234887]\n",
      " [0.239777   0.40840574 0.83590847 0.26630735 0.00977682]\n",
      " [0.34606509 0.11609104 0.49096043 0.07492482 0.82264713]\n",
      " [0.50654952 0.79143698 0.45674085 0.67474026 0.29705673]]\n",
      "\n",
      "盐噪声掩码 (random_matrix < 0.01):\n",
      "[[False False False False False]\n",
      " [False False False False False]\n",
      " [False False False False  True]\n",
      " [False False False False False]\n",
      " [False False False False False]]\n",
      "\n",
      "统计结果:\n",
      "总像素数: 25\n",
      "True的数量: 1\n",
      "实际概率: 0.040 (理论概率: 0.01)\n"
     ]
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T08:44:00.983212Z",
     "start_time": "2025-09-14T08:43:52.885430Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 原图\n",
    "cv2.imshow('salt_pepper_noisy_img', salt_peooer_noisy_img)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ],
   "id": "8cf2f20e900e5e0f",
   "outputs": [],
   "execution_count": 21
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T08:43:35.328374Z",
     "start_time": "2025-09-14T08:43:29.747751Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 均值滤波\n",
    "# 简单的平均卷积操作\n",
    "blur = cv2.blur(salt_peooer_noisy_img, (5, 5))\n",
    "\n",
    "cv2.imshow('blur', blur)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ],
   "id": "82241a457af12774",
   "outputs": [],
   "execution_count": 18
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T08:20:08.069116Z",
     "start_time": "2025-09-14T08:20:03.960937Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 方框滤波\n",
    "# 基本和均值一样，可以选择归一化\n",
    "box = cv2.boxFilter(salt_peooer_noisy_img, -1, (5, 5), normalize=True)\n",
    "cv2.imshow('box', box)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ],
   "id": "2f0bb39b6ee74622",
   "outputs": [],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T08:43:45.916220Z",
     "start_time": "2025-09-14T08:43:43.774457Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 高斯滤波\n",
    "gaussian = cv2.GaussianBlur(salt_peooer_noisy_img, (5, 5), 0)\n",
    "cv2.imshow('gaussian', gaussian)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ],
   "id": "d3c8c0e0a18d9c46",
   "outputs": [],
   "execution_count": 20
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T08:44:07.870984Z",
     "start_time": "2025-09-14T08:44:02.209230Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 中值滤波\n",
    "median = cv2.medianBlur(salt_peooer_noisy_img, 5)\n",
    "cv2.imshow('median', median)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ],
   "id": "ece7b8393f6cb336",
   "outputs": [],
   "execution_count": 22
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-09-14T08:49:52.675373Z",
     "start_time": "2025-09-14T08:49:35.516583Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 展示所有的\n",
    "res = np.hstack((salt_peooer_noisy_img, blur, box, gaussian, median))\n",
    "cv2.namedWindow('res', cv2.WINDOW_NORMAL)\n",
    "cv2.resizeWindow('res', 1600, 600)\n",
    "cv2.imshow('res', res)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ],
   "id": "eeaec1ef724ec227",
   "outputs": [],
   "execution_count": 25
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "818e6c83fc7d26b"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
